/*
 * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.love.cloud.common.security.handler;

import com.love.cloud.common.core.exception.BusinessException;
import com.love.cloud.common.core.util.R;
import com.love.cloud.common.security.exception.MyAuthenticationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.nio.file.AccessDeniedException;

/**
 * @author hongdongqu
 */
@Slf4j
@RestControllerAdvice
public class SecurityExceptionHandler {


	/**
	 * AccessDeniedException
	 * @param e the e
	 * @return R
	 */
	@ExceptionHandler(AccessDeniedException.class)
	@ResponseStatus(HttpStatus.FORBIDDEN)
	public R handleAccessDeniedException(AccessDeniedException e) {
		String msg = SpringSecurityMessageSource.getAccessor().getMessage("AbstractAccessDecisionManager.accessDenied",
				e.getMessage());
		log.error("拒绝授权异常信息 ex={}", msg, e);
		return R.failed(e.getLocalizedMessage());
	}

	@ExceptionHandler(BadCredentialsException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	private R handleBadCredentialsException(BadCredentialsException e) {
		log.error("权限校验异常 ex={}", e.getMessage(), e);
		R<Object> failed = R.failed(e.getMessage());
		failed.setCode(401);
		return failed;
	}

	@ExceptionHandler(UsernameNotFoundException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	private R handleUsernameNotFoundException(UsernameNotFoundException e) {
		log.error("权限校验异常 ex={}", e.getMessage(), e);
		R<Object> failed = R.failed(e.getMessage());
		failed.setCode(401);
		return failed;
	}

	@ExceptionHandler(MyAuthenticationException.class)
	@ResponseStatus(HttpStatus.UNAUTHORIZED)
	private R handleUsernameNotFoundException(MyAuthenticationException e) {
		log.error("权限校验异常 ex={}", e.getMessage(), e);
		R<Object> failed = R.failed(401,e.getMessage());
		if(e.getCause() instanceof BusinessException){
			BusinessException businessException=(BusinessException)e.getCause();
			failed.setCode(businessException.getCode());
		}
		return failed;
	}

}
